<template>
  <div class="markmap-container" @dblclick="handleDoubleClick">
    <svg ref="refMarkmap" style="width: 100%; height: 100%"></svg>
  </div>
</template>

<script>
import { Transformer } from "markmap-lib";
import { Markmap } from "markmap-view";

export default {
  name: "MarkmapRender",
  props: {
    content: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      mm: null,
      zoomLevel: 0,
      baseScale: 1
    };
  },
  mounted() {
    this.renderMarkmap();
  },
  watch: {
    content() {
      this.$nextTick(this.renderMarkmap);
    }
  },
  methods: {
    renderMarkmap() {
      if (!this.content) return;

      if (!this.mm) {
        const dom = this.$refs.refMarkmap;
        dom.innerHTML = "";
        this.mm = Markmap.create(
          dom,
          {
            autoFit: true,
            duration: 300
          },
          this._getContent()
        );
        this.mm.fit();
        this.baseScale = this.mm.state.scale;
        this.mm.setData(this._getContent(), { scale: this.baseScale * 0.8 });
      } else {
        this.mm.setData(this._getContent());
      }
    },
    _getContent() {
      const transformer = new Transformer();
      const { root } = transformer.transform(this.content);
      return root;
    },
    getDom() {
      return new Promise(resolve => {
        this.mm.fit().then(() => {
          resolve(this.$refs.refMarkmap);
        });
      });
    },
    handleDoubleClick() {
      if (!this.mm) return;

      this.zoomLevel = (this.zoomLevel + 1) % 4;
      const scale =
        this.baseScale * (this.zoomLevel === 0 ? 0.8 : 1.5 ** this.zoomLevel);

      this.mm.setData(this._getContent(), { scale });
    }
  }
};
</script>

<style lang="less" scoped>
.markmap-container {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
